package cn.iocoder.yudao.module.system.controller.admin.userretention;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.system.controller.admin.userretention.vo.UserRetentionPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.userretention.vo.UserRetentionRespVO;
import cn.iocoder.yudao.module.system.controller.admin.userretention.vo.UserRetentionStatsRespVO;
import cn.iocoder.yudao.module.system.dal.dataobject.userretention.UserRetentionStatsDO;
import cn.iocoder.yudao.module.system.service.userretention.UserRetentionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.time.LocalDate;
import java.util.List;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

/**
 * 用户留存率统计 Controller
 *
 * @author 芋道源码
 */
@Tag(name = "管理后台 - 用户留存率统计")
@RestController
@RequestMapping("/system/user-retention")
@Validated
public class UserRetentionController {

    @Resource
    private UserRetentionService userRetentionService;

    @GetMapping("/page")
    @Operation(summary = "获得用户留存率统计分页")
    @PreAuthorize("@ss.hasPermission('system:user-retention:query')")
    public CommonResult<PageResult<UserRetentionRespVO>> getUserRetentionPage(@Valid UserRetentionPageReqVO pageReqVO) {
        PageResult<UserRetentionRespVO> pageResult = userRetentionService.getUserRetentionPage(pageReqVO);
        return success(pageResult);
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出用户留存率统计 Excel")
    @PreAuthorize("@ss.hasPermission('system:user-retention:export')")
    public void exportUserRetentionExcel(@Valid UserRetentionPageReqVO pageReqVO,
                                         HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<UserRetentionRespVO> list = userRetentionService.getUserRetentionPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "用户留存率统计.xls", "数据", UserRetentionRespVO.class, list);
    }

    @GetMapping("/stats")
    @Operation(summary = "获得用户留存率统计概览")
    @PreAuthorize("@ss.hasPermission('system:user-retention:query')")
    public CommonResult<UserRetentionStatsRespVO> getUserRetentionStats() {
        UserRetentionStatsRespVO stats = userRetentionService.getUserRetentionStats();
        return success(stats);
    }

    @GetMapping("/{id}")
    @Operation(summary = "获得用户留存率统计详情")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('system:user-retention:query')")
    public CommonResult<UserRetentionRespVO> getUserRetention(@PathVariable("id") Long id) {
        UserRetentionRespVO retention = userRetentionService.getUserRetention(id);
        return success(retention);
    }

    @PostMapping("/calculate")
    @Operation(summary = "计算用户留存率")
    @PreAuthorize("@ss.hasPermission('system:user-retention:calculate')")
    public CommonResult<Boolean> calculateUserRetention(@RequestParam("userId") Long userId) {
        userRetentionService.calculateUserRetention(userId);
        return success(true);
    }

    @PostMapping("/calculate-batch")
    @Operation(summary = "批量计算用户留存率")
    @PreAuthorize("@ss.hasPermission('system:user-retention:calculate')")
    public CommonResult<Boolean> calculateUserRetentionBatch(@RequestParam("userIds") List<Long> userIds) {
        userRetentionService.calculateUserRetentionBatch(userIds);
        return success(true);
    }

    @PostMapping("/recalculate")
    @Operation(summary = "重新计算留存率")
    @PreAuthorize("@ss.hasPermission('system:user-retention:calculate')")
    public CommonResult<Boolean> recalculateRetention(@RequestParam("startDate") LocalDate startDate,
                                                      @RequestParam("endDate") LocalDate endDate) {
        userRetentionService.recalculateRetention(startDate, endDate);
        return success(true);
    }

    @DeleteMapping("/delete-expired")
    @Operation(summary = "删除过期留存率数据")
    @PreAuthorize("@ss.hasPermission('system:user-retention:delete')")
    public CommonResult<Integer> deleteExpiredData(@RequestParam("beforeDate") LocalDate beforeDate) {
        int deletedCount = userRetentionService.deleteExpiredData(beforeDate);
        return success(deletedCount);
    }

    @GetMapping("/pending-count")
    @Operation(summary = "获取待计算记录数")
    @PreAuthorize("@ss.hasPermission('system:user-retention:query')")
    public CommonResult<Long> getPendingCalculationCount() {
        long count = userRetentionService.getPendingCalculationCount();
        return success(count);
    }

    @GetMapping("/progress")
    @Operation(summary = "获取计算进度")
    @PreAuthorize("@ss.hasPermission('system:user-retention:query')")
    public CommonResult<Double> getCalculationProgress() {
        double progress = userRetentionService.getCalculationProgress();
        return success(progress);
    }

}